package com.zhangyan.service.impl;

import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhangyan.common.ErrorCode;
import com.zhangyan.contant.UserConstant;
import com.zhangyan.exception.BusinessException;
import com.zhangyan.mapper.UserMapper;
import com.zhangyan.model.User;
import com.zhangyan.service.UserService;
import com.zhangyan.utils.UserUtils;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;


/**
 * 用户服务实现类
 * @author zhangyan
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
        implements UserService {

    @Resource
    private UserMapper userMapper;

    /**
     * 盐值  混淆密码
     */
    private final static String SALT = "zhangyan";


    @Override
    public String userRegister(String userAccount, String userPassword, String checkPassword, String planetCode) {

        //校验参数  如果为空 "" 以及一些不可见字符返回
        if (StrUtil.hasBlank(userAccount, userPassword, checkPassword, planetCode)) {
            log.info("账户,密码,校验密码为空或\"\"");
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "账户,密码,校验密码为空或\"\"");
        }

        //校验账户长度 不能小于4
        if (userAccount.length() < 4) {
            log.info("账户长度小于4");
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "账户长度小于4");
        }

        //校验密码长度
        if (userPassword.length() < 8 || checkPassword.length() < 8) {
            log.info("密码长度小于8");
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "密码长度小于8");
        }

        if (planetCode.length() > 5) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "邀请码大于5");
        }

        //账户不能包含特殊字符
        //判断是否符合正则表达式
        boolean match = ReUtil.isMatch("^[a-zA-Z0-9]+$", userAccount);
        if (!match) {
            log.info("账户包含特殊字符");
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "账户包含特殊字符");
        }

        //账户不能重复
        // 创建一个查询条件构造器 QueryWrapper，用于动态构建查询条件
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();

        // 设置查询条件：检查数据库中的 userAccount 字段是否等于传入的 userAccount 值
        // eq 方法表示 "等于" 条件，生成的 SQL 类似于：WHERE userAccount = ?
        queryWrapper.eq("user_account", userAccount);

        // 调用 selectCount 方法统计符合条件的记录数
        // 生成的 SQL 类似于：SELECT COUNT(*) FROM user WHERE userAccount = ?
        long count = userMapper.selectCount(queryWrapper);

        // 判断是否存在符合条件的记录
        // 如果 count > 0，说明数据库中已经存在相同的 userAccount
        if (count > 0) {
            log.info("账户重复");
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "账户重复");
        }

        //邀请码不能重复
        QueryWrapper<User> queryWrapperPlanet = new QueryWrapper<>();
        queryWrapperPlanet.eq("planet_code", planetCode);
        count = userMapper.selectCount(queryWrapperPlanet);
        if (count > 0) {
            log.info("邀请码重复");
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "邀请码重复");
        }

        //密码和校验密码相同
        if (!userPassword.equals(checkPassword)) {
            log.info("密码与校验密码不同");
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "密码与校验密码不同");
        }


        //密码加密  hutul工具类
        String encryptPassword = DigestUtil.md5Hex(userPassword + SALT);

        //数据库插入数据
        User user = new User();
        user.setUserAccount(userAccount);
        user.setUserPassword(encryptPassword);
        user.setPlanetCode(planetCode);
        user.setUsername("无名氏");
        user.setAvatarUrl("https://web-framework.oss-cn-hangzhou.aliyuncs.com/2023/1.jpg");
        user.setGender(0);
        boolean save = save(user);
        if (!save) {
            log.info("数据库插入失败");
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "数据库插入失败");
        }
        log.info("插入成功,id为{}", user.getId());
        return user.getId();
    }

    @Override
    public User userLogin(String userAccount, String userPassword, HttpServletRequest request) {
        //校验参数  如果为空 "" 以及一些不可见字符返回
        if (StrUtil.hasBlank(userAccount, userPassword)) {
            log.info("账户,密码为空或\"\"");
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "账户,密码为空或\"\"");
        }

        //校验账户长度 不能小于4
        if (userAccount.length() < 4) {
            log.info("账户长度小于4");
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "账户长度小于4");
        }

        //校验密码长度
        if (userPassword.length() < 8) {
            log.info("密码长度小于8");
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "密码长度小于8");
        }

        //账户不能包含特殊字符
        //判断是否符合正则表达式
        boolean match = ReUtil.isMatch("^[a-zA-Z0-9]+$", userAccount);
        if (!match) {
            log.info("账户包含特殊字符");
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "账户包含特殊字符");
        }

        //密码加密  hutul工具类
        String encryptPassword = DigestUtil.md5Hex(userPassword + SALT);

        //账户不能重复
        // 创建一个查询条件构造器 QueryWrapper，用于动态构建查询条件
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();

        // 设置查询条件：检查数据库中的 userAccount 字段是否等于传入的 userAccount 值
        // eq 方法表示 "等于" 条件，生成的 SQL 类似于：WHERE userAccount = ?
        queryWrapper.eq("user_account", userAccount);
        queryWrapper.eq("user_password", encryptPassword);

        // 调用 selectCount 方法统计符合条件的记录数
        // 生成的 SQL 类似于：SELECT COUNT(*) FROM user WHERE userAccount = ?
        User user = userMapper.selectOne(queryWrapper);

        // 判断是否存在符合条件的记录
        // 如果 count > 0，说明数据库中已经存在相同的 userAccount
        if (user == null) {
            log.info("密码账户不匹配");
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "密码账户不匹配");
        }


        User safetyUser = UserUtils.userDesensitization(user);

        //记录用户登录态
        request.getSession().setAttribute(UserConstant.USER_LOGIN_STATE, safetyUser);
        log.info("登录用户为{}", safetyUser.toString());
        return safetyUser;
    }

    @Override
    public Page<User> searchUser(String username, int currentPage, int pageSize) {

        // 创建分页对象
        Page<User> page = new Page<>(currentPage, pageSize);
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.like("username", username);
//        userQueryWrapper.eq("username",username);
        Page<User> userPage = userMapper.selectPage(page, userQueryWrapper);
        log.info("查询到的集合为{}", userPage);
        return userPage;
    }

    @Override
    public boolean deleteUser(String id) {
        User user = userMapper.selectById(id);
        if (user.getUserRole() == UserConstant.ADMIN_ROLE) {
            throw new BusinessException(ErrorCode.NO_AUTH, "管理员无法被删除");
        }
        int i = userMapper.deleteById(id);
        if (i > 0) {
            return true;
        }
        return false;
    }

    @Override
    public int userLogout(HttpServletRequest request) {
        request.getSession().removeAttribute(UserConstant.USER_LOGIN_STATE);
        return 1;
    }

    @Override
    public boolean updateUserByRole(String id) {
        User user = new User();
        user.setId(id);
        user.setUserRole(UserConstant.ADMIN_ROLE);
        int i = userMapper.updateById(user);
        if (i > 0) {
            return true;
        }
        return false;
    }

    @Override
    public boolean updateUser(User user) {


        // 参数校验：确保 user 不为空
        if (user == null) {
            log.info("用户对象为空");
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户对象为空");
        }
        String userAccount = user.getUserAccount();
        // 如果账户为空，设置为 null
        if (StringUtils.isEmpty(userAccount)) {
            user.setUserAccount(null);
        } else {
            // 校验账户是否包含特殊字符
            boolean match = ReUtil.isMatch("^[a-zA-Z0-9]+$", userAccount);
            if (!match) {
                log.info("账户包含特殊字符");
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "账户包含特殊字符");
            }
        }
        user.setUserPassword(null);
        if (user.getEmail().isEmpty()) {
            user.setEmail(null);
        }
        if (user.getPhone().isEmpty()) {
            user.setPhone(null);
        }
        if (user.getAvatarUrl().isEmpty()) {
            user.setAvatarUrl(null);
        }
        if (user.getGender() == 2) {
            user.setGender(null);
        }
        int i = userMapper.updateById(user);
        if (i > 0) {
            return true;
        }
        return false;
    }

    /**
     * 根据标签搜索用户
     * @param tagNameList 用户要搜索的标签
     * @return
     */
    public List<User> searchUsersByTags(List<String> tagNameList){
        //判断集合是否为空 或者 ""
        if (CollectionUtils.isEmpty(tagNameList)){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        for (String tagName : tagNameList) {
            queryWrapper = queryWrapper.like("tags",tagName);
        }
        List<User> users = userMapper.selectList(queryWrapper);
        return users.stream().map(UserUtils::userDesensitization).collect(Collectors.toList());
    }
}




